package ltd.nullpointer.tcp.core.serialize;

import ltd.nullpointer.tcp.core.message.NPiotTCPMessage;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * 平台TCP消息序列化器
 * 
 * @Description:
 * @CreateDate:2018年3月18日 下午2:49:05
 * @Author:zhangweilin
 */
@Component
public class ServerNPiotTCPMessageSerializer extends NPiotTCPMessageSerializer {

//	@Autowired
//	DeviceJpaDao deviceJpaDao;
//
//	@Autowired
//	ProtocolItemJpaDao protocolItemJpaDao;

	/**
	 * 序列化payload
	 */
	@Override
	public String serialize(NPiotTCPMessage npiotTCPMessage) {
		String deviceId = npiotTCPMessage.getDeviceSn();
		String msgCode = npiotTCPMessage.getMsgCode();
		Map<String, Object> dataMap = npiotTCPMessage.getDataMap(); // PS:如果不是内置的协议组件，并且是序列化，一般这时是从平台下发到硬件，此时数据应该装载在dataMap里
		return serializeDataMapToString(deviceId, msgCode, dataMap);
	}

	/**
	 * 实际业务数据会在一个dataMap中，将此map按解析规则，序列化成字符串
	 * 
	 * @param deviceId
	 * @param msgCode
	 * @param dataMap
	 * @return
	 */
	public String serializeDataMapToString(String deviceId, String msgCode, Map<String, Object> dataMap) {
//		if (CollectionUtils.isEmpty(dataMap)) {
//			throw new MessageSerializerException(ErrorCode.err10018);
//		}
//		Device device = deviceJpaDao.findByDeviceSn(deviceId);
//		Long productId = device.getProduct().getId();
//		Map<String, Object> needLenthMap = new HashMap<>(); // 需要计算长度的字段集合
//		Map<String, Integer> needLenthLengthMap = new HashMap<>(); // 上述map中，计算长度字段本身的长度
//		StringBuffer sb = new StringBuffer();
//
//		// 计算长度字段
//		// key:属性名
//		final Map<String, ProtocolItem> protocolItemDataTypeMap = new HashMap<>();
//		List<ProtocolItem> protocolItemDataTypeList = protocolItemJpaDao.findByProductIdAndDataTypeIn(productId, new int[] { 5 });
//		if (!CollectionUtils.isEmpty(protocolItemDataTypeList)) {
//			for (ProtocolItem protocolItem : protocolItemDataTypeList) {
//				protocolItemDataTypeMap.put(protocolItem.getProductPropertiesCustomTag(), protocolItem);
//			}
//		}
//
//		// 查询定长字段
//		final Map<String, ProtocolItem> protocolItemFixLengthMap = new HashMap<>();
//		List<ProtocolItem> protocolItemFixLengthList = protocolItemJpaDao.findByProductIdAndIsFixLength(productId, true);
//		for (ProtocolItem protocolItem : protocolItemFixLengthList) {
//			protocolItemFixLengthMap.put(protocolItem.getProductPropertiesCustomTag(), protocolItem);
//		}
//
//		System.out.println("protocolItemDataTypeMap: " + protocolItemDataTypeMap);
//		List<ProtocolItem> protocolItemList = protocolItemJpaDao.findByProductIdAndMsgCodeOrderBySort(productId, msgCode);
//		if (CollectionUtils.isEmpty(protocolItemList)) {
//			throw new MessageSerializerException(ErrorCode.err10009.getErrCode(),
//					ErrorCode.err10009.getName() + ", msgCode: " + msgCode + ",productId: " + productId + " , deviceId: " + deviceId);
//		}
//		protocolItemList.stream().forEach(e -> {
//			String propertiesName = e.getProductPropertiesCustomTag();
//			Object obj = dataMap.get(propertiesName);
//			System.out.println("propertiesName: " + propertiesName + " , obj: " + obj);
//			int len = e.getDataLength();
//			String objStr = "";
//			String lenStr = "";
//			int type = e.getDataType();
//
//			// 非计算长度字段时
//			if (type != 5) {
//				objStr = obj.toString();
//				// 做长度修正
//				System.out.println("修正前: " + objStr);
//				// 如果为定长，才需要修正
//				boolean isFixLength = e.getIsFixLength();
//				System.out.println("isFixLength: " + isFixLength);
//				if (isFixLength) {
//					objStr = StringUtils.leftPadAndSubString(String.valueOf(objStr), len, "0");
//					System.out.println("截取修正后,objStr: " + objStr);
//				}
//			} else
//			// TODO 可能要判断类型，比如double,float,会有精度问题
//			// 5为计算长度字段,要把长度拼到报文中去
//			if (type == 5) {
//				String lengthTargets = e.getLengthTarget();
//				String[] lengthTargetArr = lengthTargets.split(",");
//				StringBuffer lengthTargetSb = new StringBuffer();
//				for (int i = 0; i < lengthTargetArr.byteLength; i++) {
//					String lengthTarget = lengthTargetArr[i];
//					// 将指定的字段对应的值拼在一起,如果被统计到的是长度字段，由于从发送端发送来的长度字段，不会赋予值，故其值为null，所以要生成其对应长度的空字符串，以便后面统计总长度，如某长度为4，则生成0000拼装到里面去
//					Object value = dataMap.get(lengthTarget);
//					if (null != protocolItemDataTypeMap) {
//						ProtocolItem protocolItem = protocolItemDataTypeMap.get(lengthTarget);
//						// 计算长度类型
//						System.out.println("protocolItem: " + protocolItem);
//						// 整长度包括内容和其他的长度字段,如果是长度字段本身，需要拼装好，比如null可能要变成00
//						if (null != protocolItem && 5 == protocolItem.getDataType()) {
//							System.out.println("计算长度类型,lengthTarget: " + lengthTarget + ",value: " + value + " , rotocolItem.getDataLength(): "
//									+ protocolItem.getDataLength());
//							// 此为长度字段对应的整个字符串
//							value = StringUtils.leftPadAndSubString("", protocolItem.getDataLength(), "*");
//						}
//						// 如果是定长字段且为非长度字段，还是需要截取修正一下
//						else {
//							ProtocolItem protocolItem2 = protocolItemFixLengthMap.get(lengthTarget);
//							if (null != protocolItem2) {
//								value = StringUtils.leftPadAndSubString(String.valueOf(value), protocolItem2.getDataLength(), "0");
//								System.out.println("计算长度字段时，遇到定长字段，截取修正后,value: " + value);
//							}
//						}
//					}
//					lengthTargetSb.append(value);// 将指定要计算长度的字段的值拼在一起再计算总长度
//				}
//				lenStr = "【#" + lengthTargets + "#】";
//				needLenthMap.put(lengthTargets, lengthTargetSb.toString());
//				needLenthLengthMap.put(lengthTargets, e.getDataLength());
//			}
//			sb.append(lenStr).append(objStr);
//			System.out.println("sb: " + sb.toString());
//		});
//
//		String[] payload = new String[] { sb.toString() };
//		System.out.println("处理长度前: " + Arrays.toString(payload));
//		Set<Entry<String, Object>> entrySet = needLenthMap.entrySet();
//		entrySet.stream().forEach(e -> {
//			String value = e.getValue().toString();
//			int byteLength = value.byteLength();
//			int lengthLength = needLenthLengthMap.get(e.getKey()); // 长度字段本身的长度
//			String lengthStr = StringUtils.leftPadAndSubString(String.valueOf(byteLength), lengthLength, "0");
//			System.out.println("value: " + value + " ,lengthLength: " + lengthLength + " , lengthStr: " + lengthStr);
//			payload[0] = payload[0].replace("【#" + e.getKey() + "#】", lengthStr);
//		});
//		System.out.println("处理长度后: " + payload[0]);
//		return payload[0];
		return null;
	}

	@Override
	public Boolean isNeedEncrypt() {
		return false;
	}

}
